﻿using EasyXaf.LowCode.RulesEngineEditors.UndoManagers.Commands;

namespace EasyXaf.LowCode.RulesEngineEditors.UndoManagers;

public static class UndoManagerExtensions
{
    private static void RegisterCommand(this IUndoManager undoManager, Action selector)
    {
        undoManager.RegisterCommand(new ActionCommand(selector));
    }

    public static void Execute<TRedoState, TUndoState>(
        this IUndoManager undoManager,
        TRedoState redoState,
        Func<TRedoState, TUndoState> redo,
        Func<TUndoState, TRedoState> undo)
    {
        undoManager.BeginLock();

        TUndoState undoState;
        void RedoAction()
        {
            undoState = redo(redoState);
            undoManager.RegisterCommand(UndoAction);
        }
        void UndoAction()
        {
            redoState = undo(undoState);
            undoManager.RegisterCommand(RedoAction);
        }
        RedoAction();

        undoManager.EndLock();
    }

    public static void Execute<TState>(
        this IUndoManager undoManager,
        TState redoState,
        Func<TState, TState> redoAndUndo)
    {
        undoManager.Execute(redoState, redoAndUndo, redoAndUndo);
    }
}
